package com.bluesky.objectworld.method.block;

import java.util.ArrayList;
import java.util.List;

import javax.management.RuntimeErrorException;

import com.bluesky.objectworld.World;
import com.bluesky.objectworld._Object;
import com.bluesky.objectworld.method.reference.IntegerConstant;
import com.bluesky.objectworld.method.reference.StringConstant;
import com.bluesky.objectworld.method.reference.Variable;
import com.bluesky.objectworld.method.statement.MessageStatment;

public class SequentialBlock extends Block {

	List<MessageStatment> statemnets;

	int currentIndex;

	public SequentialBlock() {
		statemnets = new ArrayList<MessageStatment>();
		currentIndex = 0;
	}

	void add(MessageStatment statement) {
		statemnets.add(statement);

	}

	public static SequentialBlock createSample(World world) {
		SequentialBlock block = new SequentialBlock();

		// null = thisBlock.declareVariable("a");
		block.add(new MessageStatment(null, new Variable("thisBlock"),
				"declareVariable", new StringConstant("\"a\"")));
		block.add(new MessageStatment(null, new Variable("thisBlock"),
				"declareVariable", new StringConstant("\"b\"")));
		block.add(new MessageStatment(null, new Variable("thisBlock"),
				"declareVariable", new StringConstant("\"c\"")));

		// a=3.self();
		block.add(new MessageStatment("a", new IntegerConstant("3"), "self"));
		// b=7.self();
		block.add(new MessageStatment("b", new IntegerConstant("8"), "self"));

		// c=a.mul(b);
		block.add(new MessageStatment("c", new Variable("a"), "mul",
				new Variable("b")));

		return block;
	}

	@Override
	public void execute() {
		// initialize some implicit variable
		updateVariable("thisBlock", this);

		for (currentIndex = 0; currentIndex < statemnets.size(); currentIndex++) {
			MessageStatment ms = statemnets.get(currentIndex);

			try {
				ms.compile(this);

				_Object[] paramObjects = new _Object[ms.messageParameters.length];
				for (int i = 0; i < paramObjects.length; i++)
					paramObjects[i] = ms.messageParameters[i].getObject();

				_Object result = ms.receiver.getObject().processMessage(
						ms.messageName, paramObjects);

				if (ms.responseVar != null) {
					Block block = locateVariableBlock(ms.responseVar);
					block.updateVariable(ms.responseVar, result);
				}
			} catch (Exception e) {
				e.printStackTrace();
				throw new RuntimeException("error when execute statement:" + ms);
			}
		}

	}
}
